<?php
namespace Tlf\User;
trait Permissions {
/**
* I will probably want to add permission lookup to the initial user loading. For this i might need to add types to permissions. For example, I DONT want to have a list of every single blog post that a user is allowed to edit (i.e. blog posts they have created). But i DO want a list of broader permissions that they have, like 'blog:create'
*
* But for now (mar 6) I just want to prototype something & have it work. I'll add this pre-fetching later, probably
*
*
*/
/**
* array of roles this user is in
* @key role_name
* @value true, always true
*/
public ?array $roles;
public function all_nonrole_permissions(){
if (!$this->is_registered())return [];
$stmt = $this->pdo->prepare($this->queries['user.all_nonrole_permissions']);
$stmt->execute(['user_id'=>$this->id]);
$rows = $stmt->fetchAll(\PDO::FETCH_COLUMN);
return $rows;
}
/**
* get all role-based permissions for the user. Will not return any roles if there are no permissions added to the role
*/
public function all_roles(){
$sql = $this->queries['user.all_roles'];
$stmt = $this->pdo->prepare($sql);
$stmt->execute(['user_id'=>$this->id]);
$rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$roles = [];
foreach ($rows as $r){
if ($r['perm']===null&&!isset($roles[$r['role']])){
$roles[$r['role']] = [];
continue;
}
$roles[$r['role']][] = $r['perm'];
}
return $roles;
}
/**
* Get array of all role names this user has
*/
public function get_all_roles(){
$sql = $this->queries['user.get_all_roles'];
$stmt = $this->pdo->prepare($sql);
$stmt->execute(['user_id'=>$this->id]);
$rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$roles = [];
foreach ($rows as $r){
$roles[$r['role']] = true;
}
return $roles;
}
/**
* check if user has role. Roles list is cached first time this is called. If you add a role after calling this, you must re-load the user or set $user->roles = null;
* @param $role_name the name of a role like `admin` or `moderator`
* @return true/false
*/
public function has_role(string $role_name): bool{
$roles = $this->roles ?? ($this->roles = $this->get_all_roles());
return isset($roles[$role_name]);
}
/**
* add a role to this user
*/
public function add_role(string $role){
if (!$this->is_registered())return false;
$stmt = $this->pdo->prepare($this->queries['user.add_role']);
$stmt->execute(['role'=>$role, 'user_id'=>$this->id]);
}
/**
* remove a role to this user
*/
public function remove_role(string $role){
if (!$this->is_registered())return false;
$stmt = $this->pdo->prepare($this->queries['user.remove_role']);
$stmt->execute(['role'=>$role, 'user_id'=>$this->id]);
}
/**
* @param $action name of an action the user can do
* @return false if we could not enable the user to take $action
*/
public function allow(string $action){
if (!$this->is_registered())return false;
$stmt = $this->pdo->prepare($this->queries['user.allow']);
$stmt->execute(['action'=>$action, 'user_id'=>$this->id]);
// print_r($this->pdo->errorInfo());
}
public function deny(string $action){
if (!$this->is_registered())return false;
$stmt = $this->pdo->prepare($this->queries['user.deny']);
$stmt->execute([
'action'=>$action,
'user_id'=>$this->id
]);
if ($stmt->rowCount()==1)return true;
return false;
}
/**
* @param $action an action the user wishes to perform
* @return true/false
*/
public function can(string $action){
$stmt = $this->pdo->prepare($this->queries['user.can']);
$stmt->execute(
['action'=>$action, 'user_id'=>$this->id]
);
// print_r($this->pdo->errorInfo());
if ($stmt->fetch()!==false){
$stmt->closeCursor();
unset($stmt);
return true;
}
return false;
}
}